
import java.io.Serializable;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Observable;
import java.util.StringTokenizer;
import java.util.StringTokenizer;
import java.util.Vector;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
/**
 * Classe controleur et application (système)
 * @author IUT,   A. Culet
 * @version 1.0 
 */

//public class Controleur extends Observable implements Serializable{

public class Controleur implements Serializable{ 


	private static final long serialVersionUID = 1L;

	/**
	 * La classe Controleur est unique pour tous les cas d'utilisation
	 * Elle est également la classe "application" qui gère l'ensemble des objets de l'appli
	 */	
	// ************************************************************************************************************
		// Attributs
		// ************************************************************************************************************

		// Attributs d'Association
		// Ensemble des ouvrages de la bibliothèque
		private HashMap<String, Ouvrage> _ouvrages; 
		// Ensemble des auteurs de la bibliothèque
		private HashMap<String, Auteur> _auteurs;
		// Ensemble des mot clés de la bibliothèque
		private HashMap<String, MotCle> _motCles;		
		// Ensemble des mot Titre de la bibliothèque
		private HashMap<String, MotTitre> _motTitres;				
		// Ensemble des periodiques de la bibliothèque
		private HashMap<String, Periodique> _periodiques;

		// les différentes fenêtres pour chaque fonctionnalité
		private VueMenuBiblio _vueMenuBiblio = null;
		
		// une seule fenêtre est active à la fois; les autres sont à null.
		// permet de connaître l'état des fenêtres de l'interface
		private VueSaisieOuvrage _vueSaisieOuvrage = null;
		private VueSaisieExemplaire _vueSaisieExemplaire = null;
		private VueConsultOuvrage _vueConsultOuvrage = null;
		private VueSaisiePeriodique _vueSaisiePeriodique =null;
		private VueSaisieParution _vueSaisieParution = null;
		private VueRechercheMotCle _vueRechercheMotCle = null;
		private VueConsultPeriodique _vueConsultPeriodique = null;
		private VueConsultAuteur _vueConsultAuteur = null;
		private VueRechercheTitre _vueRechercheTitre = null;
		
		private Object messe;
		// ************************************************************************************************************
		// Constructeur
		// ************************************************************************************************************

		public Controleur() {
			this.setOuvrages(new HashMap<String, Ouvrage>());
			this.setAuteurs(new HashMap<String, Auteur>());
			this.setMotCles(new HashMap<String, MotCle>());
			this.setPeriodiques(new HashMap<String, Periodique>());
			this.setMotTitres(new HashMap<String, MotTitre>());
			//this.initialiserMotCle();
			
		} // Fin Controleur

		// ************************************************************************************************************
		// Méthodes privées
		// ************************************************************************************************************

		// ------------------------------------------------------------------------------------------------------------
		// Affecteurs
		private void initialiserMotCle(){
			try  {	    	
		    	BufferedReader in = new BufferedReader(new FileReader("ListeAutorite.txt"));
		    	String ligne;
		    	while ((ligne= in.readLine()) != null)  {
		    		MotCle mc= new MotCle(ligne,null);
		    		_motCles.put(ligne,mc);
		    		/*** traitement de la chaine ch ***/
		    	}
		    	
		    	in.close();
		    }
		    catch (IOException e) {
		    	System.out.println("$$$$$ PB de Lecture dans le fichier XXXXX ");
		    	System.out.println();
		    }
		}
		
		
		/**
		 * Ajoute un ouvrage à l'ensemble des ouvrages de la bibliothèque.
		 * @param ouvrage 	Ouvrage à ajouter
		 * @param isbn 	code ISBN de cet ouvrage
		 */
		private void setOuvrage(Ouvrage ouvrage, String isbn) {
			this.getOuvrages().put(isbn, ouvrage);	
		}

		private void setAuteur(Auteur auteur, String identifiant) {
			this.getAuteur().put(identifiant, auteur);
		} 
		
		private void setMotCle(MotCle mc, String theme) {
			this.getMotCle().put(theme, mc);
		} 
		
		private void setMotTitre(MotTitre mt, String titre) {
			this.getMotTitre().put(titre, mt);
		} 
				
		/**
		 * @param ouvrages hashtable d'ouvrages à affecter
		 */
		private void setOuvrages(HashMap<String, Ouvrage> ouvrages) {
			_ouvrages = ouvrages;
		}// Fin setOuvrages

		private void setAuteurs(HashMap<String, Auteur> auteurs) {
			_auteurs = auteurs;
		}// Fin setAuteurs
		
		private void setMotCles(HashMap<String, MotCle> motCles) {
			_motCles = motCles;
		}// Fin setMotCles
		
		private void setMotTitres(HashMap<String, MotTitre> motTitres) {
			_motTitres = motTitres;
		}
		
		/**
		 * Ajoute un periodique à l'ensemble des périodiques de la bibliothèque.
		 * @param periodique 	Periodique à ajouter
		 * @param issn 	code ISSN de ce périodique
		 */
		private void setPeriodique(Periodique periodique, String issn) {
			this.getPeriodiques().put(issn, periodique);
		} // Fin setPeriodique

		/**
		 * @param periodiques hashtable de périodiques à affecter
		 */
		private void setPeriodiques(HashMap<String, Periodique> periodiques) {
			_periodiques = periodiques;

		}// Fin setPeriodiques		
				
		
		/**
		 * @param vue  la vue à affecter
		 */
		private void setVueMenuBiblio(VueMenuBiblio vue) {
			_vueMenuBiblio = vue;
		}// Fin getVueVueMenuBiblio
		
		private void setVueSaisieOuvrage(VueSaisieOuvrage vue) {
			_vueSaisieOuvrage = vue;
		}// Fin setVueVueSaisieOuvrage
		
		private void setVueSaisieExemplaire(VueSaisieExemplaire vue) {
			_vueSaisieExemplaire = vue;
		}// Fin setVueVueSaisieExemplaire
		
		private void setVueConsultOuvrage(VueConsultOuvrage vue) {
			_vueConsultOuvrage = vue;
		}// Fin setVueVueConsultOuvrage
		private void setVueSaisieParution(VueSaisieParution vue) {
			_vueSaisieParution = vue;
		}// Fin setVueVueConsultOuvrage
		
		private void setVueSaisiePeriodique(VueSaisiePeriodique vue) {
			_vueSaisiePeriodique = vue;
		}
		private void setVueConsultPeriodique(VueConsultPeriodique vue) {
			_vueConsultPeriodique = vue;
		}
		
		private void setVueRechercheMotCle(VueRechercheMotCle vue) {
			_vueRechercheMotCle = vue;
		}
		
		private void setVueConsultAuteur(VueConsultAuteur vue) {
			_vueConsultAuteur = vue;
		}
		private void setVueRechercheTitre(VueRechercheTitre vue) {
			_vueRechercheTitre = vue;
		}
		// ------------------------------------------------------------------------------------------------------------
		// Accesseurs
		
		/**
		 * @return ensemble des ouvrages de la bibliothèque
		 */
		private HashMap<String, Ouvrage> getOuvrages() {
			return _ouvrages;
		}// Fin getOuvrages

		private HashSet<Ouvrage> getOuv(String theme){
			HashSet<Ouvrage>listeTousOuvrage= new HashSet<Ouvrage>();
			HashSet<Ouvrage>listeOuv=new HashSet<Ouvrage>();
			for(String o: _ouvrages.keySet()){
				listeTousOuvrage.add(_ouvrages.get(o));
			}
			for(Ouvrage o: listeTousOuvrage){
				HashSet<MotCle> motCle;
				motCle=o.getMotCle();
				for(MotCle mc:motCle){
					if(theme==mc.getMotCle()){
						listeOuv.add(o);
					}
				}
			}
			return listeOuv;
		}
				
		private HashSet<Ouvrage> getOuvA(String auteur){
			HashSet<Ouvrage>listeTousOuvrage= new HashSet<Ouvrage>();
			HashSet<Ouvrage>listeOuv=new HashSet<Ouvrage>();
	    	Vector<String> aute=new Vector<String>();
	    	StringTokenizer parser = new StringTokenizer(auteur);
			while (parser.hasMoreTokens())  {
				aute.add(parser.nextToken());
			}
			for(String o: _ouvrages.keySet()){
				listeTousOuvrage.add(_ouvrages.get(o));
			}
			for(Ouvrage o: listeTousOuvrage){
				HashSet<Auteur> auts;
				auts=o.getAuteur();
				for(Auteur aut:auts){
					System.out.println(aute.elementAt(0)+aut.getNom()+aute.elementAt(1)+aut.getPrenom());
					if(aute.elementAt(0).equals(aut.getNom()) &&aute.elementAt(1).equals(aut.getPrenom()) ){
						listeOuv.add(o);
					}
				}
			}
			return listeOuv;
		}
		
		private HashSet<Ouvrage> getOuvT(String titre){
			HashSet<Ouvrage>listeTousOuvrage= new HashSet<Ouvrage>();
			HashSet<Ouvrage>listeOuv=new HashSet<Ouvrage>();
			HashSet<MotTitre>listeMotTitre=new HashSet<MotTitre>();
			for(String o: _ouvrages.keySet()){
				listeTousOuvrage.add(_ouvrages.get(o));
			}
			for(Ouvrage o: listeTousOuvrage){
				listeMotTitre=this.traiterMotTitre(o.getTitre());
				for(MotTitre mt:listeMotTitre){
					if(mt.getMot().equals(titre)){
						listeOuv.add(o);
					}
				}
			}
			return listeOuv;
		}
		
		
		private HashMap<String,Auteur> getAuteur(){
			return _auteurs;
		}
		
		private HashMap<String,MotCle> getMotCle() {
			return _motCles;
		}
		
		private HashMap<String,MotTitre> getMotTitre() {
			return _motTitres;
		}
		
		
		private HashSet<Auteur> getAuteurs() {
			HashSet<Auteur> listeAuteurs= new HashSet<Auteur>();
			if(_auteurs.size()==0){
				return null;
			}
			else{
				for(String a: _auteurs.keySet()){
					listeAuteurs.add(_auteurs.get(a));
				}
			
			return listeAuteurs;
			}
		}

		private HashSet<MotCle> getMotCles() {
			HashSet<MotCle> listeMotCles= new HashSet<MotCle>();
			/*MotCle mc;
			mc = new MotCle("aa");
			_motCles.put(mc.getMotCle(), mc);*/
			
			if(_motCles.size()==0){
				return null;
			}
			else{
				for(String a: _motCles.keySet()){
					listeMotCles.add(_motCles.get(a));
				}
			return listeMotCles;
			}

		}
		
		private HashSet<MotTitre> getMotTitres() {
			HashSet<MotTitre> listeMotTitres= new HashSet<MotTitre>();
			
			if(_motTitres==null){
				return null;
			}
			else{
				for(String a: _motTitres.keySet()){
					listeMotTitres.add(_motTitres.get(a));
				}
			return listeMotTitres;
			}
		}
			
		/**
		 * Accès à un ouvrage par son numéro ISBN
		 * @param isbn 	le code ISBN de l'ouvrage cherché
		 * @return l'ouvrage qui a l'ISBN indiqué
		 */
		private Ouvrage getOuvrage(String isbn) {
			return this.getOuvrages().get(isbn);
		} // Fin getOuvrage

		public Auteur getAuteur(String nomPrenom){
			return this.getAuteur().get(nomPrenom);
		}
			
		private MotCle getMotCle(String theme){
			return this.getMotCle().get(theme);
		}	
		/**
		 * @return ensemble des periodiques de la bibliothèque
		 */
		private HashMap<String, Periodique> getPeriodiques() {
			return _periodiques;
		}//Fin getPeriodiques
		
		/**
		 * Accès à un periodique par son numéro ISSN
		 * @param issn du périodique cherché
		 * @return le périodique qui a l'ISSN indiqué
		 */
	private Periodique getPeriodique(String issn) {
		return this.getPeriodiques().get(issn);
	}

	/**
	 * 
	 * @param issn du periodique
	 * @param numPar de la parution
	 * @return la parution du periodique de 
	 */
		private Parution getParution(String issn, String numPar) {
			Periodique perio=getPeriodique(issn);
			if (perio!=null)
				return perio.getParution(numPar);
			else
				return null;
		}

		/**
		 * @return la vue  
		 */
		private VueMenuBiblio getVueMenuBiblio() {
			return _vueMenuBiblio ;
		}// Fin getVueVueMenuBiblio
		
		private VueSaisieOuvrage getVueSaisieOuvrage() {
			return _vueSaisieOuvrage ;
		}// Fin getVueVueSaisieOuvrage
		
		private VueSaisieExemplaire getVueSaisieExemplaire() {
			return _vueSaisieExemplaire ;
		}// Fin getVueVueSaisieExemplaire
		
		private VueConsultOuvrage getVueConsultOuvrage() {
			return _vueConsultOuvrage ;
		}// Fin getVueVueConsultOuvrage
		private VueSaisieParution getVueSaisieParution() {
			return _vueSaisieParution ;
		}// Fin getVueVueSaisieParution
		
		private VueSaisiePeriodique getVueSaisiePeriodique() {
			return _vueSaisiePeriodique;
		}
		private VueConsultPeriodique getVueConsultPeriodique() {
			return _vueConsultPeriodique;
		}
		private VueRechercheMotCle getVueRechercheMotCle() {
			return _vueRechercheMotCle;
		}
		private VueConsultAuteur getVueConsultAuteur() {
			return _vueConsultAuteur;
		}
		
		private VueRechercheTitre getVueRechercheTitre() {
			return _vueRechercheTitre;
		}
		
		// ************************************************************************************************************
		// Méthodes publiques de création et affichage des fenêtres de l'application et fermeture
		// ************************************************************************************************************
		public void initMotCle(){
			this.initialiserMotCle();
			Message dialog = new Message("Thesaurus affecté");
			dialog.setVisible(true);
		}
		
		public HashSet<MotCle> recupMotCle(){
			return this.getMotCles();
		}
		/**
		 * Création et affichage de la fenêtre principale de l'application. 
		 * Elle reste affichée
		 */
		
		
		
		
		public void menuBiblio() {
			try {this.setVueMenuBiblio(new VueMenuBiblio(this));	
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		/**
		 * Création et affichage de la fenêtre de consultation d'un ouvrage
		 */
		
		public void consulterOuvrage() {
			try {this.setVueConsultOuvrage (new VueConsultOuvrage(this));
			// le Menu est caché
			this.getVueMenuBiblio().getFrame().setVisible(false); 	
			// la vue courante est VueConsultOuvrage
				this.getVueConsultOuvrage().setEtat(Vue.initiale);
				this.getVueConsultOuvrage().setVisible(true);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		/**
		 * Création et affichage de la fenêtre de saisie d'un exemplaire d'ouvrage
		 */
		public void saisirExemplaire() {
			try {this.setVueSaisieExemplaire(new VueSaisieExemplaire(this));
			// le Menu est caché
			this.getVueMenuBiblio().getFrame().setVisible(false); 
			// la vue courante est VueSaisieExemplaire
				this.getVueSaisieExemplaire().setEtat(Vue.initiale);
				this.getVueSaisieExemplaire().setVisible(true);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		/**
		 * Création et affichage de la fenêtre de saisie d'un ouvrage
		 */
		public void saisirOuvrage() {
			HashSet<Auteur> auteurs;
			HashSet<MotCle> motCles;
			auteurs=this.getAuteurs();
			motCles=this.getMotCles();
			try {this.setVueSaisieOuvrage(new VueSaisieOuvrage(this,auteurs,motCles));
			// le Menu est caché
			this.getVueMenuBiblio().getFrame().setVisible(false); 
			// la vue courante est VueSaisieOuvrage

				this.getVueSaisieOuvrage().setEtat(Vue.initiale);
				
				this.getVueSaisieOuvrage().setVisible(true);
			} catch (Exception e) {
			e.printStackTrace();
			}
		}

		
		/**
		 * Création et affichage de la fenêtre de saisie d'une parution
		 */
		public void saisirParution() {
			HashSet<Auteur> auteurs;
			HashSet<MotCle> motCles;
			auteurs=this.getAuteurs();
			motCles=this.getMotCles();
			try {this.setVueSaisieParution(new VueSaisieParution(this,auteurs,motCles));
			// le Menu est caché
			this.getVueMenuBiblio().getFrame().setVisible(false); 
			// la vue courante est VueSaisieParution
				this.getVueSaisieParution().setEtat(Vue.initiale);
				this.getVueSaisieParution().setVisible(true);
			} catch (Exception e) {
			e.printStackTrace();
			}
		}
		/**
		 * Création et affichage de la fenêtre de saisie d'un périodique
		 */
		public void saisirPeriodique() {

			try { this.setVueSaisiePeriodique(new VueSaisiePeriodique(this));
			// le Menu est caché
			this.getVueMenuBiblio().getFrame().setVisible(false);
			// la vue courante est VueSaisiePeriodique
			
			this.getVueSaisiePeriodique().setEtat(Vue.initiale);
			this.getVueSaisiePeriodique().setVisible(true);
			} catch (Exception e) {
			e.printStackTrace();
			}

		}
		/**
		 * Creation et affichage de la fenetre de consultation de periodique
		 */
		public void consulterPeriodique() {
			try { this.setVueConsultPeriodique(new VueConsultPeriodique(this));
			//le menu est cach�
			this.getVueMenuBiblio().getFrame().setVisible(false);
			//la vue courage est VueConsultPeriodique
			this.getVueConsultPeriodique().setEtat(Vue.initiale);
			this.getVueConsultPeriodique().setVisible(true);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		
		/**
		 * Cr�ation et affichage de la fen�tre de recherche par mot cl�
		 */
		public void rechercheParMotCle() {
			
			try {
				
				HashSet<MotCle> motCles;
				motCles=this.getMotCles();
				this.setVueRechercheMotCle(new VueRechercheMotCle(this,motCles));
				//le menu est cach�
				this.getVueMenuBiblio().getFrame().setVisible(false);
				//affichage de la fen�tre
				this.getVueRechercheMotCle().setVisible(true);
			} 
			catch (Exception e){
				e.printStackTrace();
			}

		}
		
		public void rechercheParTitre() {
			try {
				
				HashSet<MotTitre> motTitres;
				motTitres=this.getMotTitres();
				this.setVueRechercheTitre(new VueRechercheTitre(this,motTitres));
				//le menu est cach�
				this.getVueMenuBiblio().getFrame().setVisible(false);
				//affichage de la fen�tre
				this.getVueRechercheTitre().setVisible(true);
			} 
			catch (Exception e){
				e.printStackTrace();
			}
		
		}
		
		/**
		 * Cr�ation et affichage de la fen�tre de recherche par auteur
		 */
		public void rechercheParAuteur() {
			
//			Message dialog = new Message("Aucun auteur n'est enregistr� pour l'instant.");
//			dialog.setVisible(true);
			
			try {
				
				HashSet<Auteur> auteurs;
				auteurs=this.getAuteurs();
				if(auteurs==null){
					Message dialog = new Message("Il n'existe pas d'auteur");
					dialog.setVisible(true);
				}
				else{
					this.setVueConsultAuteur(new VueConsultAuteur(this,auteurs));
					//le menu est cach�
					this.getVueMenuBiblio().getFrame().setVisible(false);
					//affichage de la fen�tre
					this.getVueConsultAuteur().setVisible(true);
				}
			} 
			catch (Exception e){
				e.printStackTrace();
			}

		}
		
		
		
		/**
		 * fermeture de la fenêtre vue
		 * lors de la fermeture de la fenêtre principale de l'application sauvegarde des objets sérialisés 
		 */
		public void fermerVue (Vue vue) {
			if (vue instanceof VueMenuBiblio ) {	
			// Quitte l'aplication. Sauvegarde les objets du modèle
				this.sauve();
				System.exit(0);
				}
			vue.dispose();
			// le Menu est rendu de nouveau visible
			this.getVueMenuBiblio().getFrame().setVisible(true);
			this.resetVues();
		}
		
		// Restaure l'état de l'interface avec seule la fenêtre du Menu principal active
		private void resetVues() {
			this.setVueSaisieOuvrage (null);
			this.setVueConsultOuvrage(null);
			this.setVueSaisieExemplaire(null);
			this.setVueSaisiePeriodique(null);
		}
		
		// ************************************************************************************************************
		// Opérations liées à la sérialisation des objets de l'application
		// ************************************************************************************************************
		/**
		 *  restauration des objets de l'application
		 */
		public Controleur restaure() {
			try {
				FileInputStream fichier = new FileInputStream("Fsauv.ser");
				ObjectInputStream in = new ObjectInputStream(fichier);
				return((Controleur) in.readObject());
			} catch (Exception e) {
				Message dialog = new Message("Pbs de Restauration ou fichier non encore créé");
				dialog.setVisible(true);
				return this;
			} 
		}
		/**
		 *  sauvegarde des objets de l'application
		 */
		private void sauve() {
			try {
				FileOutputStream f = new FileOutputStream("Fsauv.ser");
				ObjectOutputStream out = new ObjectOutputStream(f);
				out.writeObject(this);
			} catch (Exception e) {
				Message dialog = new Message("Pb de Sauvegarde dans le fichier");
				dialog.setVisible(true);
			}
		}
		// ************************************************************************************************************
		// Opérations liées à l'application en réponse à une action de l'utilisateur dans une vue
		// ************************************************************************************************************
		
		/**
		 *Appel�e dans VueSaisieOuvrage
		 * @param isbn
		 * V�rifie si ouvrage d�j� existant, envoie un message d'erreur si oui
		 * et passe dans la saisie sinon
		 */
		public void creerOuvrage(String isbn,String titre,String editeur,String dateEdition) {
			if ((isbn.length() == 0) || (titre.length() == 0) 
					|| (editeur.length() == 0 )|| (dateEdition.length() == 0 )){
					Message dialog = new Message("Tous les champs sont obligatoires");
					dialog.setVisible(true);

					}
			else {
			GregorianCalendar date = ESDate.lireDate (dateEdition);				
			if (date == null) {
				Message dialog2 = new Message("Le format de la date est incorrect");
				dialog2.setVisible(true);
			}
			else
			{
				Ouvrage ouv;
				ouv= this.getOuvrage(isbn);
				if(ouv==null){
					this.getVueSaisieOuvrage().setEtat(Vue.finale);
				}
				else{
					Message dialog = new Message("Ouvrage déjà existant");
					dialog.setVisible(true);
				}
			}
		}
		}
		/**
		 * Accès à un ouvrage par son numéro ISBN
		 * Invoqué dans VueConsultOuvrage et VueSaisieExemplaire
		 * @param isbn 	le code ISBN de l'ouvrage cherché
		 * @return l'ouvrage qui a l'ISBN indiqué ou null
		 * affiche un message d'erreur si l'ouvrage n'est pas trouvé
		 */
		public Ouvrage rechOuvrage(String isbn) {
			Ouvrage ouv = this.getOuvrage(isbn);
			if (ouv == null) {
				Message dialog = new Message("Ouvrage inconnu");
				dialog.setVisible(true);
			}
			else {
				// la vue courante est VueSaisieExemplaire
				if (this.getVueSaisieExemplaire() != null) {
				// la vue est inscrite comme observatrice de l'ouvrage	
					ouv.addObserver(this.getVueSaisieExemplaire());
				// le contrôleur modifie l'état de la vue
					this.getVueSaisieExemplaire().setEtat(Vue.inter1);
					this.getVueSaisieExemplaire().alimente(ouv);
					}
				// la vue courante est VueConsultOuvrage
				if (this.getVueConsultOuvrage() != null) {
					// le contrôleur modifie l'état de la vue
					this.getVueConsultOuvrage().setEtat(Vue.finale);
					this.getVueConsultOuvrage().alimente(ouv);
					}
			}
			return ouv;
		} // Fin rechOuvrage
		

		/**
		 * Accès à une parution par son issn et son numPar
		 * Invoqué dans VueSaisieParution
		 * @param issn 	le code ISSN du periodique de la parution recherché
		 * @param numPar le numero de la parution recherché
		 * @return la parution qui a le periodique de l'issn et le numero de parution indiqué ou une nouvelle parution crée ou null si periodique inexistant
		 * affiche un message d'erreur si la parution existe
		 */
		public Parution rechParution(String issn, String numPar) {
			Parution par = null;
			Periodique perio = null;
			if ((issn.length() == 0) || (numPar.length() == 0) ){
					Message dialog = new Message("Tous les champs sont obligatoires");
					dialog.setVisible(true);
					}
			else {
			
				perio = this.getPeriodique(issn);
				if (perio==null) {
					Message dialog = new Message("Periodique inexistant");
					dialog.setVisible(true);

				}
				else {
				par= this.getParution(issn,numPar);
					if(par==null){
						par= new Parution(perio,numPar);
						getPeriodique(issn).addParution(numPar,par);
						this.getVueSaisieParution().setEtat(Vue.finale);
						this.getVueSaisieParution().alimente(par);	
						
					}
					else{
						Message dialog = new Message("Parution déjà existante");
						dialog.setVisible(true);
					}
				
				}

			}
			return par;
		}
		
		/**
		 * Appelée dans VueSaisiePeriodique
		 * @param issn
		 * Vérifie si periodique déjà existant, message d'erreur si oui
		 * Rentre dans �tat final sinon
		 */
		public void creerPeriodique(String issn) {
			
			if (issn.length()==0) {
				//champs d'entr� ISSN vide
				Message dialog = new Message("Entrez l'ISSN du périodique à ajouter");
				dialog.setVisible(true);
			} else if (this.getPeriodique(issn) == null) {
				//le p�riodique n'existe pas
					this.getVueSaisiePeriodique().setEtat(Vue.finale);
			} else {
				//le p�riodique existe
					Message dialog = new Message("Périodique déjà existant");
					dialog.setVisible(true);
				}
		}
			
		
		/**
		 * Accès à un périodique par son issn
		 * Invoquée dans VueSaisieParution et VueSaisieArticle
		 * @param issn
		 * @return periodique si existant
		 */
		public Periodique rechPeriodique(String issn) {
			Periodique per = this.getPeriodique(issn);
			if (per==null) {
				Message dialog = new Message("Periodique inconnu");
				dialog.setVisible(true);
			}
			else {
				if (this.getVueConsultPeriodique() != null) {
					// le contrôleur modifie l'état de la vue
					this.getVueConsultPeriodique().setEtat(Vue.finale);
					this.getVueConsultPeriodique().alimente(per);
					}
				
			}
			return per;
		}
	/*	
		public void EnregOuvrage(String isbn,String titre,String editeur, String dateEdition,HashSet<String> selectAut,HashSet<String> selectMotCles){
			Auteur auteur;
			HashSet<Auteur> ensAuteur;
			for(String s:selectAut){
				auteur=this.getAuteur(s);
				
			}
			
			
		}
		
*/
		

//>>>>>>> .r48
		/**
		 * Création d'un exemplaire d'ouvrage 
		 * Invoqué dans VueSaisieExemplaire
		 * @param ouv l'ouvrage  dateRecep la date de réception de l'exemplaire	
		 * affiche un message de confirmation après l'enregistrement ou un message d'erreur 
		 */
		public void nouvExemplaire(Ouvrage ouv, String dateReception, String statut) {
			// vérification de la présence de la date et de son format
			if (dateReception.length() == 0 ){
					Message dialog = new Message("La date de réception est obligatoire");
					dialog.setVisible(true);
					}
			else {
				GregorianCalendar date = ESDate.lireDate (dateReception);
				if (date == null) {
					Message dialog = new Message("Le format de la date est incorrect");
					dialog.setVisible(true);
					}
				else {
					int statutEx;
					if (statut == "empruntable") {
						statutEx = Exemplaire.EMPRUNTABLE ; }
					else {
						statutEx = Exemplaire.EN_CONSULTATION ; }
			// demande d'ajout de l'exemplaire
					Exemplaire exemplaire = ouv.ajouterExemplaire(date, statutEx);
			// l'opération s'est bien passée
					if (exemplaire != null) {
			// le contrôleur modifie l'état de la vue
						this.getVueSaisieExemplaire().setEtat(Vue.finale);
			// affichage d'un message de confirmation
						Message dialog = new Message("Exemplaire enregistré");
						dialog.setVisible(true);
					}
					else {
						Message dialog = new Message("Date de Reception incorrecte / à la date d'Edition.");
						dialog.setVisible(true);
					}
				}
			}
		} // Fin nouvExemplaire
		
		/**
		 * Création d'un  d'ouvrage 
		 * Invoqué dans VueSaisieOuvrage
		 * @param  dateEdition la date d'édition de l'ouvrage
		 * affiche un message de confirmation après l'enregistrement ou un message d'erreur 
		 */
		public void nouvOuvrage(String isbn, String titre, String editeur, String dateEdition,HashSet<String> selectAut,HashSet<String>selectMotCles) {

			HashSet<MotTitre> mt;
			HashSet<Auteur> listAuteur= new HashSet<Auteur>();
			HashSet<MotCle> listMotCle= new HashSet<MotCle>();
			Vector<String> nomPrenom; 
			if (this.getOuvrage(isbn )== null) {
			// Instanciation de l'ouvrage
				
				mt=traiterMotTitre(titre);
				
				//R�cuperation des auteurs
				for(String a:selectAut){
					
					Auteur aut;
					aut=getAuteur(a);
					if(aut!=null){
						listAuteur.add(aut);
						System.out.println(aut.getNom()+" "+aut.getPrenom());
					}
					else{
						nomPrenom=new Vector<String>();
						StringTokenizer parser = new StringTokenizer(a);
						while (parser.hasMoreTokens())  {
							nomPrenom.add(parser.nextToken());
						}
						aut= new Auteur(nomPrenom.get(0),nomPrenom.get(1),null);
						 _auteurs.put(nomPrenom.elementAt(0)+nomPrenom.elementAt(1), aut);
						listAuteur.add(aut);
						
					}
				}
				
				for(String mc:selectMotCles){
					MotCle theme;
					theme=getMotCle(mc);
					if(theme!=null){
						listMotCle.add(theme);
					}
				}
				GregorianCalendar date = ESDate.lireDate (dateEdition);
				Ouvrage ouvrage = new Ouvrage(isbn, titre, editeur, date,listAuteur,listMotCle,mt);
				// Ajout de l'ouvrage dans l'ensemble des ouvrages de la bibliothèque
				this.setOuvrage(ouvrage, isbn);
				
				//liaison des ouvrages aux auteurs et inversement
				for(Auteur a:listAuteur){
					ouvrage.setAuteur(a);
					a.lierDoc(ouvrage);
				}
				
				//liaison des ouvrages aux motTitres et inversement
				for(MotTitre mot:mt){
					ouvrage.setMotTitre(mot);
					mot.lierDocument(ouvrage);
				}
				
				//liaison des ouvrages aux motCles et inversement
				for(MotCle mc:listMotCle){
					ouvrage.setMotCle(mc);
					mc.lierDoc(ouvrage);
				}
				Message dialog = new Message("Ouvrage enregistré");
				dialog.setVisible(true);
				this.fermerVue (this.getVueSaisieOuvrage());
				} 
			else {
					Message dialog = new Message("Ouvrage déjà présent dans la bibliothèque");
					dialog.setVisible(true);
				}
			}// Fin nouvOuvrage
	
		/**
		 * Création de la parution
		 * Invoqué dans VueSaisieParution
		 * @param  parution, objet virtuel contenant les informations
		 * @param articles L'ensemble des articles de la parution
		 * affiche un message de confirmation après l'enregistrement ou un message d'erreur 
		 */
//		public void EnregParution(Parution parution,HashSet<Article> articles) {
//			HashMap<String, Article> dicoArticles = new HashMap<String, Article>();
//			for (Article article:articles)
//				dicoArticles.put(article.getTitre(), article);
//			parution.setArticles(dicoArticles);
//		}
		
		/**
		 * Création d'un article 
		 * Invoqué dans VueSaisieParution
		 * @param  titre le titre de l'article
		 * @param  numpage le numero de la 1ere page de l'article
		 * @param  selectAut Les auteurs selectionn�s pour l'article
		 * @param  selectMotCles Les mots cles selectionn�s pour l'article
		 * affiche un message de confirmation après l'enregistrement ou un message d'erreur 
		 * @return 
		 */
		public Article nouvArticle(Parution parution,String titre, String numPage, HashSet<String> selectAut,HashSet<String>selectMotCles) {
			
			Article article = null;
			HashSet<MotTitre> mt;
			HashSet<Auteur> listAuteur= new HashSet<Auteur>();
			HashSet<MotCle> listMotCle= new HashSet<MotCle>();
			Vector<String> nomPrenom= new Vector<String>();
			if (selectMotCles.size()!=0) {
				if (selectAut.size()!=0) {
					if (numPage.length()!=0) {
						int numeroPage =  Integer.parseInt(numPage);
						if (titre.length()!=0) {
							
							mt=traiterMotTitre(titre);
							
							//R�cuperation des auteurs
							for(String a:selectAut){
								
								Auteur aut;
								aut=getAuteur(a);
								if(aut!=null){
									listAuteur.add(aut);
									System.out.println(aut.getNom()+" "+aut.getPrenom());
								}
								else{
									nomPrenom=new Vector<String>();
									StringTokenizer parser = new StringTokenizer(a);
									while (parser.hasMoreTokens())  {
										nomPrenom.add(parser.nextToken());
									}
									aut= new Auteur(nomPrenom.get(0),nomPrenom.get(1),null);
									 _auteurs.put(nomPrenom.elementAt(0)+nomPrenom.elementAt(1), aut);
									listAuteur.add(aut);
									
								}
							}
							
							for(String mc:selectMotCles){
								MotCle theme;
								theme=getMotCle(mc);
								if(theme!=null){
									listMotCle.add(theme);
								}
							}
							article = new Article(numeroPage, titre, parution,listAuteur ,listMotCle , mt);
							
							//liaison des ouvrages aux auteurs et inversement
							for(Auteur a:listAuteur){
								article.setAuteur(a);
								a.lierDoc(article);
							}
							
							//liaison des ouvrages aux motTitres et inversement
							for(MotTitre mot:mt){
								article.setMotTitre(mot);
								mot.lierDocument(article);
							}
							
							//liaison des ouvrages aux motCles et inversement
							for(MotCle mc:listMotCle){
								article.setMotCle(mc);
								mc.lierDoc(article);
							}
							Message dialArtEnr = new Message("Article enregistré");
							dialArtEnr.setVisible(true);
						}
						else {
								Message dialog = new Message("Champ Titre obligatoire");
								dialog.setVisible(true);
						}
					}
					else {
						Message dialog = new Message("Champ Page obligatoire");
						dialog.setVisible(true);

					}
				}
				else {
					Message dialog = new Message("Ajouter au moins un Auteur");
					dialog.setVisible(true);
				}
			}
			else {
				Message dialog = new Message("Ajouter au moins un Theme");
				dialog.setVisible(true);
			}
			this.getVueSaisieParution().setEtat(Vue.finale);		
			
			return article;
		}
		
			private HashSet<MotTitre> traiterMotTitre(String titre) {
				Vector<String> vectMotVide;
				boolean ajouter=true;
				/*****************************************/
				/*   Extraction des mots d'une chaine    */
				/*****************************************/
				HashSet<String> verif = new HashSet<String>();
				HashSet<MotTitre> mt = new HashSet<MotTitre>();
				StringTokenizer parser = new StringTokenizer(titre);
				while (parser.hasMoreTokens())  {
					verif.add(parser.nextToken());
				}
				// R�cuperation des mots vides
				vectMotVide= new Vector<String>();
			    try  {	    	
			    	BufferedReader in = new BufferedReader(new FileReader("ListeMotsVides.txt"));
			    	String ligne;
			    	while ((ligne= in.readLine()) != null)  {
			    		vectMotVide.add(ligne);
			    	}
			    	in.close();
			    }
			    catch (IOException e) {
			    	System.out.println("$$$$$ PB de Lecture dans le fichier XXXXX ");
			    	System.out.println();
			    }
			    
			    for (String mot : verif)
			    {
			    		if(vectMotVide.contains(mot))
			    		{
			    			ajouter=false;
			    		}
			    	
			    	if(ajouter==true){
			    		mt.add(ChercheAjoute(mot));
			    		
			    	}	
			    	ajouter=true;
			    }
			    
				return mt;
		}
			


		private MotTitre ChercheAjoute(String mot) {
				// Cherche le mot titre si il n'existe pas le cr��
				HashSet<MotTitre> mt=getMotTitres();
				MotTitre m = null;
				boolean ajoute=true;
				if(mt!=null){
					for(MotTitre titre: mt){
						if(titre.getMot()==mot){
							ajoute=false;
							m=titre;
						}
					}
				}
				if(ajoute==true){
				    m= new MotTitre(mot,null);
				    if(_motTitres==null){
				    	_motTitres= new HashMap<String, MotTitre>();
				    }
					_motTitres.put(mot, m);
				}
				
				return m;
			}

		/**
		 * Création d'un périodique
		 * Invoqué dans VueSaisiePeriodique
		 * @param issn, nom
		 * affiche un message de confirmation après l'enregistrement ou un message d'erreur et éventuellement envoie a saisieParution()
		 */

		public void nouvPeriodique( String issn, String nom) {
			if (nom.length()==0) {
				//champs nomP vide
				Message dialog = new Message("Le nom du périodique est obligatoire");
				dialog.setVisible(true);
			}
			else {
					//le test sur l'existance du p�riodique se fait avant dans creerPeriodique()
					//Instanciation du périodique
					Periodique periodique = new Periodique(issn, nom);
					// Ajout du périodique dans l'ensemble des périodiques de la bibliothèque
					this.setPeriodique(periodique, issn);
					
					Message dialog = new Message("Périodique enregistré");
					dialog.setVisible(true);
					this.fermerVue(this.getVueSaisiePeriodique());				
			}
		}

		
		
		public HashSet<Ouvrage> RechercheParMotCleOuv(String selectTheme){
			
			HashSet<Ouvrage> listOuv;
			
			listOuv=this.getOuv(selectTheme);
			return listOuv;
		}

		public HashSet<Article> RechercheParMotCleArt(String selectTheme){
			
			HashSet<Article> listArt=new HashSet<Article>();
			HashSet<Periodique>listePeriodique=new HashSet<Periodique>();
			HashSet<Parution> listeParution=new HashSet<Parution>();
			HashSet<Article> listeTousArt=new HashSet<Article>();
			HashSet<MotCle> listeMotCle=new HashSet<MotCle>();
			for(String o: _periodiques.keySet()){
				listePeriodique.add(_periodiques.get(o));
			}
			for(Periodique per:listePeriodique){
				listeParution.addAll(per.getParutions());
				System.out.println(per.getIssn());
			}
			for(Parution par:listeParution){
				System.out.println("par"+par.getNumPar());
				listeTousArt.addAll(par.getArticles());
			}
			
			for(Article art:listeTousArt){
				System.out.println(art.getTitre());
				listeMotCle=art.getMotCle();
					for(MotCle mc:listeMotCle){
						if(mc.getMotCle().equals(selectTheme)){
							listArt.add(art);
						}
					}
				}
			return listArt;
		}
		
		public HashSet<Ouvrage> RechercheParAuteurOuv(String selectAuteur){
			
			HashSet<Ouvrage> listOuv;
			
			listOuv=this.getOuvA(selectAuteur);
			return listOuv;
		}

		public HashSet<Article> RechercheParAuteurArt(String auteur){
			
			HashSet<Article> listArt=new HashSet<Article>();
			HashSet<Periodique>listePeriodique=new HashSet<Periodique>();
			HashSet<Parution> listeParution=new HashSet<Parution>();
			HashSet<Article> listeTousArt=new HashSet<Article>();
			HashSet<Auteur> listAuteur=new HashSet<Auteur>();
			Vector<String> aute=new Vector<String>();
			for(String o: _periodiques.keySet()){
				listePeriodique.add(_periodiques.get(o));
				
			}
			for(Periodique per:listePeriodique){
				listeParution.addAll(per.getParutions());
			
			}
			for(Parution par:listeParution){
				
				listeTousArt.addAll(par.getArticles());
			}
			
			for(Article art:listeTousArt){
				listAuteur=art.getAuteur();
					for(Auteur aut:listAuteur){
				    	StringTokenizer parser = new StringTokenizer(auteur);
						while (parser.hasMoreTokens())  {
							aute.add(parser.nextToken());
						}
						if(aute.elementAt(0).equals(aut.getNom()) &&aute.elementAt(1).equals(aut.getPrenom()) ){
							listArt.add(art);
						}
					}	
			}
			return listArt;
		}
		
		public HashSet<Ouvrage> RechercheParTitreOuv(String selectTitre){
			
			HashSet<Ouvrage> listOuv;
			
			listOuv=this.getOuvT(selectTitre);
			return listOuv;
		}
		
		public HashSet<Article> RechercheParTitreArt(String selectTitre){
			HashSet<Article> listArt=new HashSet<Article>();
			HashSet<Periodique>listePeriodique=new HashSet<Periodique>();
			HashSet<Parution> listeParution=new HashSet<Parution>();
			HashSet<Article> listeTousArt=new HashSet<Article>();
			HashSet<MotTitre> listTitre=new HashSet<MotTitre>();
			for(String o: _periodiques.keySet()){
				listePeriodique.add(_periodiques.get(o));
			}
			for(Periodique per:listePeriodique){
				listeParution.addAll(per.getParutions());
			}
			for(Parution par:listeParution){
				listeTousArt.addAll(par.getArticles());
			}
			for(Article art:listeTousArt){
				listTitre=this.traiterMotTitre(art.getTitre());
					for(MotTitre mt:listTitre){
						if(mt.getMot().equals(selectTitre)){
							listArt.add(art);
						}
				}
			}
			return listArt;
		}
}//public void nouvExemplaire(Ouvrage ouv, String dateReceptio>>>>>>> .r27
